package examples.rulesets;

import framework.interfaces.Cell;
import framework.interfaces.RuleSet;

/**
 * A RuleSet plugin that sets up a simulation of Conway's Game of Life
 * with a blank grid.
 */
public class Conway implements RuleSet{
	
	private static final boolean TOROIDAL = true;
	private static final int NUM_ROWS = 60;
	private static final int NUM_COLS = 60;
	private static final int NEIGHBORHOOD_SIZE = 8;
	private static final int NUM_STATES = 2;
	private static final int DEFAULT_STATE = 0;
	private static int[][] startingGrid = null;
	private static final int startingMachineState = 0;
	
	//States
	private static final int DEAD = 0;
	private static final int ALIVE = 1;
	
	/* Conway's Game of Life
	 * A cell with 2 ALIVE neighbors will maintain its state
	 * A DEAD cell with 3 ALIVE neighbors will become ALIVE
	 * Otherwise a cell will become/remain DEAD
	 */
	@Override
	public int getNextState(Cell active) {
		int liveNeighbors = active.getNeighborCount(ALIVE);
		
		if(active.getState() == ALIVE && 
		   (liveNeighbors == 2 || liveNeighbors == 3)){
			//If cell is alive and has 2 or 3 neighbors, it stays alive
			return ALIVE;
		}
		if(active.getState() == DEAD && liveNeighbors == 3){
			//If cell is dead, and has exactly 3 neighbors, it becomes alive
			return ALIVE;
		}
		//Otherwise, cell is dead
		return DEAD;
	}
	
	@Override
	public boolean getToroidal() {
		return TOROIDAL;
	}
	@Override
	public int getGridRows() {
		return NUM_ROWS;
	}
	@Override
	public int getGridCols() {
		return NUM_COLS;
	}
	@Override
	public int getNeighborhoodSize() {
		return NEIGHBORHOOD_SIZE;
	}
	@Override
	public int getNumStates() {
		return NUM_STATES;
	}
	@Override
	public int getDefaultState() {
		return DEFAULT_STATE;
	}

	@Override
	public int[][] getStartingGrid() {
		return startingGrid;
		//The blank grid is fine for this demo
	}

	@Override
	public int getStartingMachineState() {
		return startingMachineState;
		//Conway doesn't have a machine state
	}

	@Override
	public String[] getStateNames() {
		return null;
		//Conway only has 2 states, so names don't matter
	}
	
}